package com.wetech.demo.web3j.service;

import com.wetech.demo.web3j.contracts.ljy_erc20.LJY_ERC20;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.web3j.crypto.Credentials;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.methods.response.TransactionReceipt;
import org.web3j.tx.gas.ContractGasProvider;

import java.math.BigInteger;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Slf4j
@Service
@RequiredArgsConstructor
public class LJY_ERC20Service {

    private final Web3j web3j;
    private final Credentials credentials;
    private final ContractGasProvider gasProvider;

    private LJY_ERC20 contract;

    @Getter
    private String contractAddress;

    // 部署合约
    public CompletableFuture<String> deployContract() {
        log.info("Deploying LJY_ERC20 contract...");
        return LJY_ERC20.deploy(web3j, credentials, gasProvider)
                .sendAsync()
                .thenApply(contract -> {
                    this.contract = contract;
                    this.contractAddress = contract.getContractAddress();
                    log.info("LJY_ERC20 contract deployed to: {}", contractAddress);
                    return contractAddress;
                });
    }

    // 加载现有合约
    public void loadContract(String contractAddress) {
        log.info("Loading LJY_ERC20 contract from address: {}", contractAddress);
        this.contract = LJY_ERC20.load(contractAddress, web3j, credentials, gasProvider);
        this.contractAddress = contractAddress;
    }

    // 获取代币名称
    public CompletableFuture<String> name() {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        return contract.name().sendAsync();
    }

    // 获取代币符号
    public CompletableFuture<String> symbol() {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        return contract.symbol().sendAsync();
    }

    // 获取小数位数
    public CompletableFuture<BigInteger> decimals() {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        return contract.decimals().sendAsync();
    }

    // 获取总供应量
    public CompletableFuture<BigInteger> totalSupply() {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        return contract.totalSupply().sendAsync();
    }

    // 获取余额
    public CompletableFuture<BigInteger> balanceOf(String address) {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        return contract.balanceOf(address).sendAsync();
    }

    // 转账
    public CompletableFuture<TransactionReceipt> transfer(String to, BigInteger value) {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        log.info("Transferring {} tokens to {}", value, to);
        return contract.transfer(to, value).sendAsync();
    }

    // 添加这个新方法，支持指定合约地址的transferFrom
    public CompletableFuture<TransactionReceipt> transferFromWithContract(
            String contractAddress,  // 代币合约地址
            String from,             // 代币拥有者
            String to,               // 接收者
            BigInteger value) {      // 转账数量

        // 为这次调用临时加载指定的代币合约
        LJY_ERC20 tempContract = LJY_ERC20.load(contractAddress, web3j, credentials, gasProvider);

        log.info("Transferring {} tokens from {} to {} using contract {}", value, from, to, contractAddress);
        return tempContract.transferFrom(from, to, value).sendAsync();
    }

    // 授权
    public CompletableFuture<TransactionReceipt> approve(String spender, BigInteger value) {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        log.info("Approving {} tokens for spender {}", value, spender);
        return contract.approve(spender, value).sendAsync();
    }

    // 查询授权额度
    public CompletableFuture<BigInteger> allowance(String owner, String spender) {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        return contract.allowance(owner, spender).sendAsync();
    }

    // 代理转账
    public CompletableFuture<TransactionReceipt> transferFrom(String from, String to, BigInteger value) {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        log.info("Transferring {} tokens from {} to {}", value, from, to);
        return contract.transferFrom(from, to, value).sendAsync();
    }

    // 铸造代币 (自定义方法)
    public CompletableFuture<TransactionReceipt> mint(String to, BigInteger value) {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        log.info("Minting {} tokens to {}", value, to);
        return contract.mint(to, value).sendAsync();
    }

    // 销毁代币 (自定义方法)
    public CompletableFuture<TransactionReceipt> burn(BigInteger value) {
        if (contract == null) throw new IllegalStateException("Contract not deployed or loaded");
        log.info("Burning {} tokens", value);
        return contract.burn(value).sendAsync();
    }
}